import React, { useState, useEffect } from 'react';
import { connect } from 'dva';
import {
  DatePicker,
  Select,
  Input,
  Button,
  Form,
  TreeSelect,
  Modal,
  Card,
  Row,
  Col,
  message,
  InputNumber,
  Radio,
  Upload,
  Tabs,
  ConfigProvider,
} from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import Editor from '@/components/Ueditor';
import zhCN from 'antd/lib/locale/zh_CN';
import Uploader from '../Uploader';
import styles from './index.less';
import Download from '../Download';
const { TabPane } = Tabs;
const { TextArea } = Input;

type Rules = {
  required: boolean;
};

type OptionType = {
  label?: string;
  value: any;
};
type EditItem = {
  key: string;
  type: string;
  label: string;
  rules?: Array<Rules>;
  placeholder?: string;
  mode?: 'multiple' | 'tags' | undefined;
  options?: Array<OptionType>;
  render?: React.ReactElement;
  format?: string;
  span: number;
  prop: any; //节点内联属性
  disabled?: boolean;
  hidden?: boolean;
};
type Props = {
  filters: Array<{ title: string; list: Array<EditItem> }>;
  dispatch: Function;
  onClose: Function;
  title?: string;
  initialValues?: object;
  formLayout?: object;
  onSave: any; // 保存成功回调
  source: string;
  readOnly?: boolean;
  preproccess?: Function;
  updateUrl: string; //保存地址
  footer?: Boolean;
};
const dateFormat = 'YYYY/MM/DD';
const defaultLayout = {
  labelCol: { span: 4 },
  wrapperCol: { span: 16 },
};
export const firstToUpper = (str: string) =>
  str.charAt(0).toUpperCase() + str.substr(1);

const Index = ({
  filters,
  dispatch,
  onClose,
  title,
  initialValues,
  formLayout = defaultLayout,
  onSave,
  source,
  readOnly,
  preproccess,
  updateUrl,
  footer,
}: Props) => {
  const [form] = Form.useForm();
  let [opts, setOpts] = useState({});
  let editor = null;
  const getInputComp = (filter: EditItem) => {
    let {
      key,
      type,
      label,
      mode, // 添加select多选模式，数据目前放在sumit回调给主页面去处理
      placeholder,
      options,
      rules,
      render,
      format,
      span,
      prop = {},
      disabled,
    } = filter;
    let result = null;
    // select options 为对象时，需要异步请求数据 option为字符串时(define.js里面自己定义的数据 不需要异步请求)
    // eslint-disable-next-line no-underscore-dangle
    options = options || opts[key];
    if (
      (readOnly || type == 'text' || (prop && prop.readOnly)) &&
      initialValues
    ) {
      let content = '';
      // 处理多层嵌套问题
      if (Array.isArray(key)) {
        content = initialValues;
        key.forEach(k => {
          content = content ? content[k] : '暂无数据';
        });
      } else if (type == 'upload') {
        content = initialValues[key] || [];
        content = content.map(item => (
          <Download {...item}>{item.name}</Download>
        ));
      } else if (type == 'tabs') {
        content = (
          <Tabs {...prop}>
            {options &&
              options.map(item => (
                <TabPane tab={item.label} key={item.value} />
              ))}
          </Tabs>
        );
      } else if (type == 'textarea') {
        let list = initialValues[key] ? initialValues[key].split('\n') : [];
        content = (
          <div style={{ minHeight: '50px', paddingTop: '4px' }}>
            {list.map((it, k) => (
              <div key={key}>{it}</div>
            ))}
          </div>
        );
      } else {
        // 正常处理数据
        content = initialValues[key] || '';
        if (~['select', 'radiogroup'].indexOf(type)) {
          let opt = options?.find(item => item.value == initialValues[key]);
          content = opt ? opt.label : '暂无数据';
        }
        content = content.name || content || '暂无数据';
        if (prop && prop.addonAfter) {
          content += prop.addonAfter;
        }
      }

      result = render ? render : <div>{content}</div>;
    } else {
      switch (type) {
        case 'text':
          if (initialValues && initialValues[key]) {
            if (typeof initialValues[key] == 'string') {
              result = <div>{initialValues[key]}</div>;
            } else {
              result = <div>{initialValues[key].name}</div>;
            }
          } else {
            result = <div> </div>;
          }

          // result = <div>222</div>;
          break;
        case 'input':
          result = (
            <Input
              allowClear
              placeholder={placeholder}
              {...prop}
              disabled={disabled}
            />
          );
          break;
        case 'inputnumber':
          result = <InputNumber placeholder={title} style={{ width: 240 }} />;
          break;
        case 'password':
          result = (
            <Input.Password placeholder={title} style={{ width: 240 }} />
          );
          break;
        case 'textarea':
          result = (
            <TextArea
              allowClear
              placeholder={placeholder}
              {...prop}
              disabled={disabled}
            />
          );
          break;
        case 'datepicker':
          result = <DatePicker allowClear disabled={disabled} {...prop} />;
          break;
        case 'select':
          result = (
            <Select
              optionFilterProp="children"
              placeholder={placeholder}
              allowClear
              mode={mode}
              disabled={disabled}
              {...prop}
            >
              {options &&
                options.map((v, i) => (
                  <Select.Option key={i} value={v.value}>
                    {v.label}
                  </Select.Option>
                ))}
            </Select>
          );
          break;
        case 'radiogroup':
          result = (
            <Radio.Group {...prop}>
              {options &&
                options.map((v, i) => (
                  <Radio key={i} value={v.value}>
                    {v.label}
                  </Radio>
                ))}
            </Radio.Group>
          );
          break;

        case 'ueditor':
          result = <Editor {...prop} />;
          break;
        case 'upload':
          result = <Uploader {...prop} key={key} />;
          break;
        case 'tabs':
          result = (
            <Tabs {...prop}>
              {options &&
                options.map(item => (
                  <TabPane tab={item.label} key={item.value} />
                ))}
            </Tabs>
          );
          break;
        default:
          result = render || (
            <Input
              allowClear
              placeholder={placeholder}
              {...prop}
              disabled={disabled}
            />
          );
      }
    }
    return (
      <Form.Item
        key={key}
        label={label}
        name={key}
        rules={rules}
        labelCol={{ span: span == 12 ? 6 : 3 }}
        wrapperCol={{ span: span == 12 ? 16 : label ? 20 : 24 }}
      >
        {React.cloneElement(result, filter)}
      </Form.Item>
    );
  };
  const onCancle = () => {
    dispatch({
      type: '$router/back',
    });
  };

  const onOk = async () => {
    const validate = await form.validateFields().catch(e => {
      message.error('请正确填写表单');
    });
    if (!validate) return;
    let data = form.getFieldsValue();
    data = Object.assign({}, initialValues, data);
    // 时间数据处理成时间戳
    Object.keys(data).forEach(key => {
      if (data[key] && data[key].hasOwnProperty('_isAMomentObject')) {
        data[key] = +data[key];
      }
    });
    data = preproccess ? preproccess(data) : data; //父级有特殊处理

    dispatch({
      type: '$request/post',
      payload: {
        url: updateUrl,
        data: data,
      },
    }).then(() => {
      message.success('保存成功');
      onSave
        ? onSave(data)
        : dispatch({
            type: '$router/back',
          });
    });
  };

  useEffect(() => {
    // console.log('update', initialValues);
    form.setFieldsValue(initialValues);
  });

  useEffect(() => {
    console.log(initialValues);
    filters.forEach(group => {
      if (Array.isArray(group.list)) {
        let keys: any = [],
          pros: any = [];
        group.list.forEach(({ options, key, type, asyncopt }: any) => {
          if (asyncopt && asyncopt.url) {
            keys.push(key);
            pros.push(
              dispatch({
                type: `$request/post`,
                payload: {
                  url: asyncopt.url,
                  data: { page: 0, size: 20, ...asyncopt.data },
                },
              }),
            );
          }
        });

        Promise.all(pros).then((res: Array<any>) => {
          keys.forEach((key: string, index: number) => {
            let list = (res[index].dataList || res[index]).map((item: any) => {
              return {
                label: item.name || item.display,
                value: item.uuid,
              };
            });
            opts[key] = list;
          });
          setOpts({ ...opts });
        });
      }
    });
  }, [filters]);
  return (
    <ConfigProvider locale={zhCN}>
      <Row className={styles.container}>
        {filters && filters.length > 0 && (
          <Form {...formLayout} form={form} style={{ width: '100%' }}>
            {filters.map((group, uni) => (
              <Card title={group.title} key={uni} type="inner">
                <Row>
                  {group.list
                    .filter(f => !f.hidden)
                    .map((key, index) => (
                      <Col span={key.span} key={index}>
                        {getInputComp(key)}
                      </Col>
                    ))}
                </Row>
              </Card>
            ))}
          </Form>
        )}

        <Row className={styles.footer}>
          {footer}
          {!readOnly && (
            <Button type="primary" onClick={() => onOk()}>
              确认
            </Button>
          )}

          <Button className={styles.cancel} onClick={() => onCancle()}>
            {readOnly ? '返回' : '取消'}
          </Button>
        </Row>
      </Row>
    </ConfigProvider>
  );
};
export default connect((state: any) => state)(Index);
